#! /usr/bin/env python
# -*- coding: utf-8 -*-

import re
import os
import time
import random
import traceback

import FileHostProtoType


class hostitem(FileHostProtoType.HostItem):
    def __init__(self, name, type, id, link, encrypt_name='', server_name=''): 
        FileHostProtoType.HostItem.__init__(self, name, type, id, link, encrypt_name, server_name)
        
class slingfile(FileHostProtoType.FileHostProcess):
    def __init__(self,user,pwd):
        FileHostProtoType.FileHostProcess.__init__(self)
        self.hostname = "SlingFile.com"
        self._opener = None
        self._user = user
        self._pwd = pwd
        self.islogin = False
        self._ftppwd = ''
        
    def loginFileHost(self,loginurl,logindata):
        return FileHostProtoType.FileHostProcess.loginFileHost(self, loginurl, logindata)

    def login(self):
        '''
        login to slingfile
        return opener object which includes cookies
        '''
        self.generateOpener()
        if self.check_cookie():
            return True
        self.post_request('http://www.slingfile.com/')
        self.fherr.write('login to slingfile %s/%s...'%(self._user,'*'*len(self._pwd)))
        loginData = {'f_user' : self._user, \
                'f_password' : self._pwd,
                'submit' : 'Login »',
                'f_keepMeLoggedIn' : '1' }
        response = self.loginFileHost("http://www.slingfile.com/login", loginData)

        if self._user.lower() not in response.lower():
            self.fherr.write("User %s Failed to Login slingfile." % self._user)
            return False
        self.fherr.write("User %s logined." % self._user)
        self.islogin = True
        return True
    
    def check_cookie(self):
        return self.islogin
    
    def check_login(self):
        if self.check_cookie():
            return
        self.fherr.write('cookie unavaiable, reLogin...')
        while not self.login():
            time.sleep(5)
    
    def getFileList(self):
#        folders = self.getFolderList()
#        root = f4sitem('root','/root','0','')
#        folders.append(root)
#        files = []
#        self.fherr.write("Listing files...")
#        for f in folders:
#            files.extend(self.getFilesFromFolder(f))
#        files.sort()
#        return files
        return self.exportLinks()
        
    
    def getFileFromRoot(self):
        root = hostitem('root','/root','0','')
        return self.getFilesFromFolder(root)

    def exportLinks(self):
        data = {'getcsv':'1'}
        url = "http://www.slingfile.com/file-manager"
        response = self.post_request(url, data)  
        return self.pasterItemFromCSV(response)
    
    def pasterItemFromCSV(self, csvdata):
        fileList = []
        itemLines = csvdata.split('\n')
        itemLines.pop(0)
        for itemLine in itemLines:
            if not itemLine.strip():
                continue
            itemTokens = itemLine.split(',')
            name = itemTokens[1]
            type = 'file'
            link = itemTokens[3]
            item = hostitem(name, type, id, link)
            fileList.append(item)
        fileList.sort()
        return fileList
        
    def getFilesFromFolder(self, folder):
        '''
        TODO: deal with pages
        '''
        
        files = []
        folde_id  = folder.id
        page = 1
#        while True:
#            print 'page: %s'% page
#            url = "http://slingfile.com/?op=my_files&fld_id=%s&page=%s" % (folde_id, page) 
#            self.fherr.write("Getting files from folder...%s" % folder.name)
#            response = self.post_request(url)
#            reFileEntity = re.compile('<TD><input type="checkbox" name="file_id" value="(?P<file_id>\d+)"></TD>.*?<TD align=left><a href="(?P<file_link>[^"]+)">(?P<file_name>.*?)</a></TD>', re.S|re.I)
#            result_iter = reFileEntity.finditer(response)
#            has_file_flag = False
#            for r in result_iter:
#                has_file_flag = True
#                id = r.group("file_id")
#                name = r.group("file_name")
#                link = r.group("file_link")
#                fsI = hostitem(name,'file',id,link)
#                files.append(fsI)
#            if not has_file_flag:
#                break
#            page += 1
#        files.sort()
        return files
    
    def getFolderList(self):   
        self.fherr.write("Getting folder list...") 
        foundFolders = []
        url = "http://www.slingfile.com/file-manager"
        response = self.post_request(url)
        s_pos = response.find('<select name="folderToMove" id="folderToMove">')
        e_pos = response.find('</select>', s_pos)
        folder_context = response[s_pos:e_pos]
        reFolder = re.compile('<option .*?value="(?P<folder_id>.*?)">(?P<folder_name>.*?)</option>',re.I|re.S)
        result_iter = reFolder.finditer(folder_context)
        for r in result_iter:
            name = r.group('folder_name')
            #exclude root
            if name == '/':
                continue
            id = r.group('folder_id')
            item = hostitem(name, 'folder', id, 
                          'http://www.slingfile.com/folder/%s.html' % id)
            foundFolders.append(item)
        foundFolders.sort()
        return foundFolders
    
    def find(self, filenames=[], filelist = None):
        '''
        open the filelist page according to opener with cookies
        '''
        found = []
        if filelist is None:
            filelist = self.getFileList()        
        filelistlower = [fl.name.lower() for fl in filelist]
        todel = []
        for fl in filenames:
            try:
                index = filelistlower.index(os.path.basename(fl).lower())
                found.append(filelist[index])
                todel.append(fl)
            except:
                continue
        for d in todel:
            filenames.remove(d)
        found.sort()
        return found

    def findFolder(self, foldername):        
        folders = self.getFolderList()
        for f in folders:
            if foldername == f.name:
                return f
        return None

    def createFolder(self, newfolder):
        foundfolder = self.findFolder('/' + newfolder)
        if foundfolder is None:
            #f4s don't support subdir 
            return self.__newFolder(newfolder)
        self.fherr.write("Folder %s exsits." % newfolder)
        return foundfolder

    def __newFolder(self, newfolder, parentfolder=None):
        '''
        newfolder : without any '/',just a standard folder name
        '''
        print('Creating new folder: %s' % newfolder)
        data = {'createfolder':'Create Folder »',
                'foldername':newfolder}
        url = "http://www.slingfile.com/file-manager"
        self.post_request(url, data)  
        time.sleep(5)
        return self.findFolder('/' + newfolder)
    
    def moveto(self, items, destFolder):
        if len(items) == 0:
            return
        print('Moving...')
        data =[]
        data.append(('movefolder','    Move to Folder »'))
        data.append(('folderToMove', destFolder.id))
        for item in items:
            data.append(('fileids[]', item.id))
        print data
        url = "http://www.slingfile.com/file-manager"
        self.post_request(url, data)
        print('Moved.')
    
    def upload_web(self, file, progressLog=None, other_args=None):
        return self.upload_to_ftp(file, progressLog, other_args)
       
    def upload_web_local(self, file, progressLog=None, other_args=None):
        pass

    def upload_to_ftp(self, file, progressLog=None, other_args=None):
        url = 'ftp.slingfile.com'
        userpwd = ('%s:%s' % (self._user, self._pwd)).encode('utf8')
        target_name = self.rename_func(file).encode('utf8')
        callback = None
        if progressLog is not None:
            callback = progressLog.write
            
        retry = 9        
        while retry > 0:
            try:
                self.fherr.write('upload %s to %s' % (file,url))
                self.upload_file_to_ftp(url, userpwd, file, target=target_name, callback=callback)
            except:
                self.fherr.write(traceback.format_exc())
                time.sleep(60)
                retry -= 1
                continue
            break
        if retry == 0:
            self.fherr.write('max retry. failed')
            return
            
        #find new upload file:
        time.sleep(60)
        times = self.wait_time/60 + 1
        if not self.check_cookie():
            self.login()
        while times > 0:            
            root = hostitem('root','/root','D0','')
            rootfiles = self.getFilesFromFolder(root)
            find_result = self.find([target_name.decode('utf8'),], rootfiles)
            if find_result:
                new_file = find_result[0]     
                item = hostitem(os.path.basename(file), \
                              'file', \
                              new_file.id, \
                              new_file.link, \
                              target_name.decode('utf8'),\
                              new_file.server_name)
                self.newupload.append(item)
                return item
            times -= 1
            time.sleep(60)    

if __name__ == "__main__":
    pass